#!/usr/bin/env python

# copyright 2010 Studio Cypher, LLC
# developer: Will Emigh
# projects@studiocypher.com

# Custom modules
from authentication import user_required
from authentication import get_account_from_user
from models import Account
from models import Good
from models import Offer
from models import Log
from models import Colony

# Built-in or Google modules
import cgi
import os
from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users
from google.appengine.ext.webapp.util import login_required
from google.appengine.ext import db

class ViewPage(webapp.RequestHandler):

    @user_required
    def get(self):
        user = users.get_current_user()
        account = get_account_from_user(user)
        
        offer_sort = self.request.get("o_s")
        if (offer_sort == 'any'):
            offer_sort = None
        request_sort = self.request.get("r_s")
        if (request_sort == 'any'):
            request_sort = None
        
        all_offers = Offer.all()
        all_offers = all_offers.filter('location =', account.current_planet)
        all_goods = Good.all()
        
        template_values = {
            'account': account,
            'offer_sort': offer_sort,
            'request_sort': request_sort,
            'all_offers': all_offers,
            'goods': all_goods,
            }

        path = os.path.join(os.path.dirname(__file__), 'market.html')
        self.response.out.write(template.render(path, template_values))
        
class OfferPage(webapp.RequestHandler):
    # They want to add an offer to the market
    def post(self):
        user = users.get_current_user()
        account = get_account_from_user(user)
        
        if account == None:
            self.redirect('/accounts/login')
            return
                        
        # Get their offer
        sets = self.request.get("sets")
        offer = self.request.get("offer")
        units = self.request.get("units")
        request = self.request.get("request")
        
        # Do some error checking
        error_msgs = []
        
        # Make sure they have all pieces of the offer
        if (sets == None or offer == None or units == None or request == None) or (sets == '' or offer == '' or units == '' or request == ''):
            error_msgs.append("All parts of an offer are necessary.")
                    
        # Make sure they have the goods they want to sell
        
        if offer != None and sets != None and offer != '' and sets != '':
            value = int(sets)*10
            """
            for good in account.valid_goods():
                if good.name == offer:
                    if good.amount < value:
                        msg = "You need "+str(value)+" "+good.name+" for "
                        msg += sets+" sets but you only have "
                        msg += str(good.amount)+"."
                        error_msgs.append(msg)
                    break
            """            
        # Make sure they use numbers greater than 0
        if sets != None and sets != '' and units != None and units != '':
            if int(sets) <= 0 or int(units) <= 0:
                error_msgs.append("All offers must use positive numbers.")
        
        all_goods = Good.all()
        all_offers = Offer.all()
        all_offers = all_offers.filter('location =', account.current_planet)
        
        # Make sure the goods are valid
        try:
            Good.all().index(offer)
        except:
            error_msgs.append("C'mon, "+offer+" isn't a real good.")
            
        try:
            Good.all().index(request)
        except:
            error_msgs.append("C'mon, "+request+" isn't a real good.")
                    
        # If they have any errors, re-display the market page with them
        if len(error_msgs) > 0:
            template_values = {
                'account': account,
                'error_msgs': error_msgs,
                'sets':sets,
                'all_offers':all_offers,
                #'offer': offer,
                'units':units,
                'request':request,
                'goods': all_goods,
                }

            path = os.path.join(os.path.dirname(__file__), 'market.html')
            self.response.out.write(template.render(path, template_values))
            return
            
        # If everything's fine, create their offer
        
        # Create the Offer
        o = Offer()
        o.owner = account
        o.offer_good = offer
        o.offer_amount = value
        o.request_good = request
        o.request_amount = int(units)
        o.location = account.current_planet
        #o.universe = account.universe
        o.put()

        # Remove the offered goods from the user's account
        thisColony = Colony.get_colony(account, account.current_planet)
        Offer.update_good(thisColony, offer, -value)
        
        # Redirect back to the market
        self.redirect('/market/view')
                            
class CancelPage(webapp.RequestHandler):
    # They want to cancel an offer
    def post(self):
        user = users.get_current_user()
        account = get_account_from_user(user)
        
        if account == None:
            self.redirect('/accounts/login')
            return
        
        # Get the offer and make sure it exists and is theirs
        offer = db.get(db.Key(self.request.get("id")))
        if offer == None or offer.owner.key() != account.key():
            self.redirect('/market/view')
            return
            
        # Give them back their good
        offerColony = Colony.get_colony(offer.owner, offer.location)
        Offer.update_good(offerColony, offer.offer_good, offer.offer_amount)
        offer.delete()
        self.redirect('/market/view')
        
class BuyPage(webapp.RequestHandler):
    # They want to buy an offer
    def post(self):
        user = users.get_current_user()
        account = get_account_from_user(user)
        
        if account == None:
            self.redirect('/accounts/login')
            return
        
        # Get the offer and make sure it exists and isn't theirs
        offer = db.get(db.Key(self.request.get("id")))
        if offer == None or offer.owner.key() == account.key():
            self.redirect('/market/view')
            return
            
        # Make sure they want a valid amount
        amount = self.request.get("amount")
        if amount == None or amount == '' or int(amount) <= 0:
            self.redirect('/market/view')
            return
        # Has to be a multiple of 10
        amount = int(amount)
        if amount % 10 != 0:
            self.redirect('/market/view')
            return
        # Has to be less than the number of sets offered
        if amount > offer.offer_amount:
            self.redirect('/market/view')
            return
        
        # Make sure they have enough goods to pay
        # They might do this one by mistake, so they need an error message
        myColony = Colony.get_colony( account, account.current_planet)
        owned_good_amount = myColony.good_amount_for(offer.request_good)
        cost = int(offer.request_amount*amount/10)
        if  cost > owned_good_amount:
            msg = "You need "+str(cost)+" "
            msg += offer.request_good+" but you only have "
            msg += str(owned_good_amount)+"."
            template_values = {
                'account': account,
                'error_msgs': [msg],
                }

            path = os.path.join(os.path.dirname(__file__), 'market.html')
            self.response.out.write(template.render(path, template_values))
            return
        
        
        offerColony = Colony.get_colony(offer.owner, offer.location)
        # Remove the correct amount of their good from them
        Offer.update_good(myColony, offer.request_good, -offer.request_amount)
        # Give those goods to the other dude and log it
        Offer.update_good(offerColony, offer.request_good, offer.request_amount)
        # Get your part of the deal
        Offer.update_good(myColony, offer.offer_good, offer.offer_amount )

        msg = str(account.user)+" traded you "+str(cost)+" "
        msg += offer.request_good+" for "+str(amount)+" "+offer.offer_good
        Log.log(offer.owner, msg)
        
        # Remove the correct number of sets from the offer and save
        if offer.offer_amount == amount:
            offer.delete()
        else:
            offer.offer_amount -= amount
            offer.put()
        
        # Add the correct amount of the offered good to them
        #account.update_good(offer.offer_good, amount)
        self.redirect('/market/view')
        return
                            
application = webapp.WSGIApplication(
                                     [('/market/view', ViewPage),
                                      ('/market/offer', OfferPage),
                                      ('/market/cancel', CancelPage),
                                      ('/market/buy', BuyPage)],
                                     debug=True)									 
def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()